package com.scwatch.core.web.back;

import com.alibaba.fastjson.JSONObject;
import com.scwatch.common.orm.RowSide;
import com.scwatch.common.web.Servlets;
import com.scwatch.core.constant.Constants;
import com.scwatch.core.domain.*;
import com.scwatch.core.html.HtmlGenerator;
import com.scwatch.core.service.*;
import com.scwatch.core.support.Backends;
import com.scwatch.core.support.CmsException;
import com.scwatch.core.support.Context;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.web.PageableDefault;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.scwatch.core.constant.Constants.*;

/**
 * SpecialController
 * 专题栏目管理
 * @author gjl
 * 
 */
@Controller
@RequestMapping("/core/special")
public class SpecialController {
	private static final Logger logger = LoggerFactory
			.getLogger(SpecialController.class);

    /**
     * 专题查询
     * @param pageable 分页对象
     * @param parentId 父专题
     * @param request
     * @param modelMap
     * @return 结果页面
     */
//	@RequiresPermissions("core:special:list")
	@RequestMapping("list.do")
	public String list(
			@PageableDefault(sort = {"priority", "creationDate"}, direction = Sort.Direction.DESC) Pageable pageable,
			Integer parentId,
			HttpServletRequest request, org.springframework.ui.Model modelMap) {
		Integer siteId = Context.getCurrentSiteId();
		Map<String, String[]> params = Servlets.getParamValuesMap(request,
				Constants.SEARCH_PREFIX);
        params.put("EQ_level",new String[]{"0"});
        if(parentId!=null){
            params.put("EQ_parent.id",new String[]{parentId.toString()});
            params.put("EQ_level",new String[]{"1"});
        }
		Page<Special> pagedList = service.findAll(siteId, params, pageable,0);
		modelMap.addAttribute("pagedList", pagedList);

		List<SpecialCategory> categoryList = specialCategoryService
				.findList(siteId);
		modelMap.addAttribute("categoryList", categoryList);
        modelMap.addAttribute("parentId", parentId);
        Integer[] queryNodeIds=getNodeIdsByFlag(Constants.SPECIAL_MANAGEMENT,siteId);
        if(queryNodeIds!=null && queryNodeIds.length>0){
            modelMap.addAttribute("queryNodeId", queryNodeIds[0]);
        }

		return "core/special/special_list";
	}

//	@RequiresPermissions("core:special:create")
	@RequestMapping("create.do")
	public String create(Integer id, Integer modelId, Integer categoryId,
			HttpServletRequest request, org.springframework.ui.Model modelMap) {
		Integer siteId = Context.getCurrentSiteId();
		Model model = null;
		SpecialCategory category = null;
		if (id != null) {
			Special bean = service.get(id);
			Backends.validateDataInSite(bean, siteId);
			if (bean != null) {
				model = bean.getModel();
				category = bean.getCategory();
			}
			modelMap.addAttribute("bean", bean);
		}
		if (categoryId != null) {
			category = specialCategoryService.get(categoryId);
			Backends.validateDataInSite(category, siteId);
		}
		if (modelId != null) {
			model = modelService.get(modelId);
		}
		if (model == null) {
			model = modelService.findDefault(siteId, Special.MODEL_TYPE);
		}
		if (model == null) {
			throw new CmsException("special.error.modelNotFound");
		}
		List<SpecialCategory> categoryList = specialCategoryService
				.findList(siteId);
		List<Model> modelList = modelService.findList(siteId,
				Special.MODEL_TYPE);
		modelMap.addAttribute("categoryList", categoryList);
		modelMap.addAttribute("category", category);
		modelMap.addAttribute("model", model);
		modelMap.addAttribute("modelList", modelList);

		modelMap.addAttribute(OPRT, CREATE);
		return "core/special/special_form";
	}

//	@RequiresPermissions("core:special:edit")
	@RequestMapping("edit.do")
	public String edit(
			Integer id,
			Integer modelId,
			Integer position,
            Integer parentId,
			@PageableDefault(sort = "id", direction = Direction.DESC) Pageable pageable,
			HttpServletRequest request, org.springframework.ui.Model modelMap) {
		Integer siteId = Context.getCurrentSiteId();
		Special bean = service.get(id);
		Backends.validateDataInSite(bean, siteId);
		Model model = bean.getModel();
		if (modelId != null) {
			model = modelService.get(modelId);
		}
		Map<String, String[]> params = Servlets.getParamValuesMap(request,
				Constants.SEARCH_PREFIX);
		RowSide<Special> side = service.findSide(siteId, params, bean,
				position, pageable.getSort(),0);
		modelMap.addAttribute("bean", bean);
		modelMap.addAttribute("side", side);
		modelMap.addAttribute("position", position);

		List<SpecialCategory> categoryList = specialCategoryService
				.findList(siteId);
		List<Model> modelList = modelService.findList(siteId,
				Special.MODEL_TYPE);
		modelMap.addAttribute("categoryList", categoryList);
		modelMap.addAttribute("category", bean.getCategory());
		modelMap.addAttribute("modelList", modelList);
		modelMap.addAttribute("model", model);
        modelMap.addAttribute("parent",bean.getParent());
        modelMap.addAttribute("parentId",parentId);

		modelMap.addAttribute(OPRT, EDIT);
		return "core/special/special_form";
	}

    /**
     * 保存专题
     * @param bean 专题对象
     * @param categoryId 分类
     * @param modelId 模型
     * @param imagesName 图片名称
     * @param imagesText 图片文本
     * @param imagesImage 图片
     * @param filesName 文件名称
     * @param filesFile 文件
     * @param filesLength 文件大小
     * @param parentId 父专题
     * @param redirect
     * @param request
     * @param ra
     * @return 结果页面
     */
//	@RequiresPermissions("core:special:save")
	@RequestMapping("save.do")
	public String save(Special bean, Integer categoryId, Integer modelId,
			String[] imagesName, String[] imagesText, String[] imagesImage,
			String[] filesName, String[] filesFile, Long[] filesLength,
            Integer parentId,
			String redirect, HttpServletRequest request, RedirectAttributes ra) {
		Integer siteId = Context.getCurrentSiteId();
		Integer userId = Context.getCurrentUserId();
		bean.setUser(Context.getCurrentUser());
		//父级专题
        bean.setLevel(0); //级别默认0
        if (parentId != null) {
            Special parent = service.get(parentId);
            Backends.validateDataInSite(parent, siteId);
            if(parent.getParent()!=null){
                ra.addFlashAttribute(MESSAGE,SPEC_NOT_PARENT);
                return "redirect:create.do";
            }
            bean.setParent(parent);
            bean.setLevel(1); //如果有父专题 子专题
        }
		SpecialCategory category = specialCategoryService.get(categoryId);
		Backends.validateDataInSite(category, siteId); 
		Map<String, String> customs = Servlets.getParamMap(request,
				"customs_");
		Map<String, String> clobs = Servlets.getParamMap(request, "clobs_");
		List<SpecialImage> images = new ArrayList<SpecialImage>();
		if (imagesName != null) {
			SpecialImage specialImage;
			for (int i = 0, len = imagesName.length; i < len; i++) {
				if (StringUtils.isNotBlank(imagesName[i])
						|| StringUtils.isNotBlank(imagesText[i])
						|| StringUtils.isNotBlank(imagesImage[i])) {
					specialImage = new SpecialImage(imagesName[i],
							imagesText[i], imagesImage[i]);
					images.add(specialImage);
				}
			}
		}
		List<SpecialFile> files = new ArrayList<SpecialFile>();
		if (filesName != null) {
			SpecialFile specialFile;
			for (int i = 0, len = filesFile.length; i < len; i++) {
				if (StringUtils.isNotBlank(filesName[i])
						&& StringUtils.isNotBlank(filesFile[i])) {
					specialFile = new SpecialFile(filesName[i], filesFile[i],
							filesLength[i]);
					files.add(specialFile);
				}
			}
		}
		bean.setPriority(0); //优先级默认0
        bean.setPublish(1); //发布状态默认1
		service.save(bean, categoryId, modelId, userId, customs, clobs, images,
				files, siteId);
		logService.operation("opr.special.add", bean.getTitle(), null,
				bean.getId(), request);
		logger.info("save Special, title={}.", bean.getTitle());
		ra.addFlashAttribute(MESSAGE, SAVE_SUCCESS);
		if (Constants.REDIRECT_LIST.equals(redirect)) {
			return "redirect:list.do";
		} else if (Constants.REDIRECT_CREATE.equals(redirect)) {
			return "redirect:create.do";
		} else {
			ra.addAttribute("id", bean.getId());
			return "redirect:edit.do";
		}
	}

    /**
     * 修改专题
     * @param bean 专题对象
     * @param categoryId 分类
     * @param modelId 模型
     * @param imagesName 图片名称
     * @param imagesText 图片文本
     * @param imagesImage 图片
     * @param filesName 文件名称
     * @param filesFile 文件
     * @param filesLength 文件大小
     * @param position 数据位置
     * @param parentId 父栏目
     * @param redirect
     * @param request
     * @param ra
     * @return 结果页面
     */
//	@RequiresPermissions("core:special:update")
	@RequestMapping("update.do")
	public String update(@ModelAttribute("bean") Special bean,
			Integer categoryId, Integer modelId, String[] imagesName,
			String[] imagesText, String[] imagesImage, String[] filesName,
			String[] filesFile, Long[] filesLength, Integer position,Integer parentId,
			String redirect, HttpServletRequest request, RedirectAttributes ra) {
		Site site = Context.getCurrentSite();
		SpecialCategory category = specialCategoryService.get(categoryId);

        //父级专题
        if (parentId != null) {
            Special parent = service.get(parentId);
            Backends.validateDataInSite(parent, site.getId());
            if(parentId.intValue()==bean.getId().intValue()){
                ra.addFlashAttribute(MESSAGE,SPEC_SAME);
                ra.addAttribute("id", bean.getId());
                ra.addAttribute("position", position);
                return "redirect:edit.do";
            }
            if(bean!=null && bean.getChildren()!=null && bean.getChildren().size()>0){
                ra.addFlashAttribute(MESSAGE,SPEC_EXIST_CHILD);
                ra.addAttribute("id", bean.getId());
                ra.addAttribute("position", position);
                return "redirect:edit.do";
            }
            if(parent.getParent()!=null){
                ra.addFlashAttribute(MESSAGE,SPEC_NOT_PARENT);
                ra.addAttribute("id", bean.getId());
                ra.addAttribute("position", position);
                return "redirect:edit.do";
            }
            bean.setParent(parent);
            bean.setLevel(1); //如果有父专题 子专题 级别1
        }else{
            bean.setParent(null);
            bean.setLevel(0); //父专题 级别0
        }
		Backends.validateDataInSite(category, site.getId());
		Backends.validateDataInSite(bean, site.getId());
		Map<String, String> customs = Servlets.getParamMap(request,
				"customs_");
		Map<String, String> clobs = Servlets.getParamMap(request, "clobs_");
		List<SpecialImage> images = new ArrayList<SpecialImage>();
		if (imagesName != null) {
			SpecialImage specialImage;
			for (int i = 0, len = imagesName.length; i < len; i++) {
				if (StringUtils.isNotBlank(imagesName[i])
						|| StringUtils.isNotBlank(imagesText[i])
						|| StringUtils.isNotBlank(imagesImage[i])) {
					specialImage = new SpecialImage(imagesName[i],
							imagesText[i], imagesImage[i]);
					images.add(specialImage);
				}
			}
		}
		List<SpecialFile> files = new ArrayList<SpecialFile>();
		if (filesName != null) {
			SpecialFile specialFile;
			for (int i = 0, len = filesFile.length; i < len; i++) {
				if (StringUtils.isNotBlank(filesName[i])
						&& StringUtils.isNotBlank(filesFile[i])) {
					specialFile = new SpecialFile(filesName[i], filesFile[i],
							filesLength[i]);
					files.add(specialFile);
				}
			}
		}
        if(bean.getPriority()==null){
            bean.setPriority(0); //优先级默认0
        }
        if(bean.getPublish()==null){
            bean.setPublish(1); //发布状态默认1
        }
        if(bean.getLevel()==null){
            bean.setLevel(0); //级别默认0
        }
		service.update(bean, categoryId, modelId, customs, clobs, images, files);
		logService.operation("opr.special.edit", bean.getTitle(), null,
				bean.getId(), request);
		logger.info("update Special, title={}.", bean.getTitle());
		ra.addFlashAttribute(MESSAGE, SAVE_SUCCESS);
		ra.addAttribute("parentId",parentId);
		if (Constants.REDIRECT_LIST.equals(redirect)) {
			return "redirect:list.do";
		} else {
			ra.addAttribute("id", bean.getId());
			ra.addAttribute("position", position);
			return "redirect:edit.do";
		}
	}

    /**
     * 删除专题
     * @param ids 专题id
     * @param request
     * @param ra
     * @return 结果页面
     */
//	@RequiresPermissions("core:special:delete")
	@RequestMapping("delete.do")
	public String delete(Integer[] ids, HttpServletRequest request,
			RedirectAttributes ra) {
		Site site = Context.getCurrentSite();
		validateIds(ids, site.getId());
		Special[] beans = service.delete(ids);
		for (Special bean : beans) {
			logService.operation("opr.special.delete", bean.getTitle(), null,
					bean.getId(), request);
			logger.info("delete Special, title={}.", bean.getTitle());
		}
		ra.addFlashAttribute(MESSAGE, DELETE_SUCCESS);
		return "redirect:list.do";
	}




    //	---------------------------------------------
    //@RequiresPermissions("core:special:delete")
    @RequestMapping("updateDelStatus.do")
    public String updateDelStatus(Integer[] ids, HttpServletRequest request,
                         Integer parentId,
                         RedirectAttributes ra) {
        Site site = Context.getCurrentSite();
        validateIds(ids, site.getId());
        List<Info> infoSpecs=infoQuery.findInfoBySpecAndSite(ids[0],site.getId());
        Special spec=service.get(ids[0]);
        if(infoSpecs!=null &&  infoSpecs.size()>0 && spec.getPublish()==0){
            ra.addFlashAttribute(MESSAGE,SPEC_REF);
            return "redirect:list.do";
        }
        if(spec!=null && spec.getParent()==null && spec.getPublish().intValue()==0){
            ra.addFlashAttribute(MESSAGE,SPEC_PUBLISH);
            return "redirect:list.do";
        }
        List<Integer> idlist=new ArrayList<>();
        idlist.add(ids[0]);
        if(spec.getChildren()!=null && spec.getChildren().size()>0){
           for(Special spe:spec.getChildren()){
               idlist.add(spec.getId());
           }
        }
        Integer[] specIds=new Integer[idlist.size()];
        specIds=idlist.toArray(specIds);
        Special[] beans = service.updateDelStatus(specIds,1);
        for (Special bean : beans) {
            logService.operation("opr.updateDelStatus.delete", bean.getTitle(), null, bean.getId(), request);
            logger.info("delete updateDelStatus, title={}.", bean.getTitle());
        }
        ra.addAttribute("parentId",parentId);
        ra.addFlashAttribute(MESSAGE, DELETE_SUCCESS);
        return "redirect:list.do";
    }

    /**
     * 生成专题
     * @param ra
     * @param specId 专题id
     * @param request
     * @param modelMap
     * @return 结果页面
     */
    @RequestMapping("generationSpec.do")
    @RequiresRoles("super")
    @RequiresPermissions("core:special:generationSpec")
    public String generationSpec(RedirectAttributes ra,Integer specId,
                                 HttpServletRequest request,org.springframework.ui.Model modelMap) {
        Site site=Context.getCurrentSite();
        User user=Context.getCurrentUser();
        Special special=service.get(specId);
//        if(special==null || special.getPublish().intValue()==1){  //未发布时，生成，需修改为已发布
            service.updatePublish(specId,0);  //专题去掉判断，只要生成json，修改为发布，同时生成搜索索引
//        }
        Node rootnode=nodeQuery.findRoot(site.getId());
        htmlGenerator.generationSpec(site,specId,rootnode);
        String ip = Servlets.getRemoteAddr(request);
        logService.operation("opr.generationSpec","生成专题", null,specId,ip,user.getId(), site.getId());
        logger.info("generationSpec json");
        ra.addFlashAttribute(MESSAGE, SAVE_SUCCESS);
        return "redirect:list.do";
    }

    /**
     * 修改发布状态
     * @param ra
     * @param specId 专题
     * @param request
     * @param modelMap
     * @return 结果页面
     */
    @RequestMapping("updatePublish.do")
    @RequiresRoles("super")
    @RequiresPermissions("core:special:updatePublish")
    public String updatePublish(RedirectAttributes ra,Integer specId,
                                 HttpServletRequest request,org.springframework.ui.Model modelMap) {
        Site site=Context.getCurrentSite();
        User user=Context.getCurrentUser();
        Special special=service.get(specId);
        if(special!=null){
            //修改为未发布 ，需要判断有没有其他栏目引用
            if(special.getPublish()!=null && special.getPublish().intValue()==0){
              List<Info> infoSpecs=infoQuery.findInfoBySpecAndSite(special.getId(),site.getId());
              if(infoSpecs!=null && infoSpecs.size()>0){
                  ra.addFlashAttribute(MESSAGE,SPEC_REF);
                  return "redirect:list.do";
              }
            }else{
                Node rootnode=nodeQuery.findRoot(site.getId());
                htmlGenerator.generationSpec(site,specId,rootnode);
            }
            service.updatePublish(specId,null);
            htmlGenerator.deleteSpecHtml(site,service.get(specId));
        }
        String ip = Servlets.getRemoteAddr(request);
        logService.operation("opr.updatePublish","切换专题状态", null,specId,ip,user.getId(), site.getId());
        logger.info("updatePublish specId:{},userId:{}",specId,user.getId());
        ra.addFlashAttribute(MESSAGE, SAVE_SUCCESS);
        return "redirect:list.do";
    }

    /**
     * 修改专题优先级
     * @param priority 优先级
     * @param specId 专题
     * @param request
     * @return 结果页面
     */
    @RequestMapping("updatePriority.do")
    @RequiresRoles("super")
//    @RequiresPermissions("core:special:updatePriority")
    @ResponseBody
    public String updatePriority(Integer priority,Integer specId,
                                 HttpServletRequest request) {
        String msg="success";
        Site site=Context.getCurrentSite();
        User user=Context.getCurrentUser();
        String ip = Servlets.getRemoteAddr(request);
        if(specId!=null && priority!=null){
            Special special=service.get(specId);
            if(special!=null){
                special.setPriority(priority);
                service.updateSpecial(special);
            }else{
                msg="fail";
            }
            logService.operation("opr.special.updatePriority","设置专题优先级:"+msg, priority.toString(),specId, ip, user.getId(), site.getId());
            logger.info("updatePriority,specId={}.",specId);
        }
        JSONObject json = new JSONObject();
        JSONObject jsons = new JSONObject();
        jsons.put("msg",msg);
        return jsons.toJSONString();
    }

    /**
     * 推送专题
     * @param request
     * @param specId 专题
     * @param title 推送标题
     * @return 结果页面
     */
    @RequestMapping("jpushSpec.do")
    @RequiresPermissions("core:special:jpushSpec")
    @ResponseBody
    public String jpushSpec(HttpServletRequest request,
                                 Integer specId, String title) {
        User user = Context.getCurrentUser();
        Site site = Context.getCurrentSite();
        JSONObject json = new JSONObject();
        try {
        /*---------------------------------[ 推送格式 ]--------------------------------------------*/
            Special special=service.get(specId);
            if(special==null ||(special!=null && special.getLevel()==1) || (special!=null && special.getPublish()==1) || (special!=null && StringUtils.isBlank(special.getJsonUrl()))){
                json.put("msg", "data_error");
                return json.toJSONString();
            }

            JSONObject extr = new JSONObject();
            extr.put("newsId", special.getId());//0正常、1推送直播间动态、2聊天室
            extr.put("newsTitle",special.getTitle()==null?"":special.getTitle());
            extr.put("newsUrl", special.getJsonUrl()==null?"":special.getJsonUrl());
            extr.put("newsType", 4);//专题

             /*-----[封装 评论数据]------*/
            String newTitle = StringUtils.isEmpty(title) ? special.getTitle() : title;
            json.put("title", newTitle);//通知内容标题
            json.put("msgTile", newTitle);//消息内容标题
            json.put("content", "专题");//消息内容
            json.put("isOpen", false);//是否静默
            json.put("groupTag", null);//分组直播间
            json.put("extrasparam", extr);//扩展字段
            boolean isfo = jpushService.JpushIosOrAndroid(site, user, json);
            json.clear();
            String msg = "error";
            if (isfo) {
                msg = "success";
            }
            json.put("msg", msg);
        } catch (Exception e) {
            json.put("msg", "error");
        }
        return json.toJSONString();
    }
//---------------------------------------------------

    private Integer[] getNodeIdsByFlag(String modelFlag,Integer siteId) {
        Integer [] nodeIds=null;
        Map<String,String[]> paramMap=new HashMap<String,String[]>();
        paramMap.put("EQ_flag",new String[]{modelFlag});
        List<Model> models=modelService.findList(siteId,null,paramMap,null);

        paramMap=new HashMap<String,String[]>();
        String[] idsStr;
        if(models!=null && models.size()>0){
            idsStr=new String[models.size()];
            for(int i=0;i<models.size();i++){
                idsStr[i]=models.get(i).getId().toString();
            }
            paramMap.put("EQ_nodeModel.id",idsStr);
        }
        Sort paramSort=new Sort(Sort.Direction.ASC, "treeNumber", "id");
        List<Node>  currentNodeList=nodeQuery.findList(siteId,null,
                null,null,true,
                paramMap, paramSort);
        if(currentNodeList!=null){
            nodeIds=new Integer[currentNodeList.size()];
            for(int i=0;i<currentNodeList.size();i++){
                nodeIds[i]=(currentNodeList.get(i).getId());
            }
        }
        return  nodeIds;
    }

    @ModelAttribute("bean")
	public Special preloadBean(@RequestParam(required = false) Integer oid) {
		return oid != null ? service.get(oid) : null;
	}

	private void validateIds(Integer[] ids, Integer siteId) {
		for (Integer id : ids) {
			Backends.validateDataInSite(service.get(id), siteId);
		}
	}

	@Autowired
	private OperationLogService logService;
	@Autowired
	private ModelService modelService;
	@Autowired
	private SpecialCategoryService specialCategoryService;
	@Autowired
	private SpecialService service;
    @Autowired
    private HtmlGenerator htmlGenerator;
    @Autowired
    private NodeQueryService nodeQuery;
    @Autowired
    private InfoQueryService infoQuery;
    @Autowired
    private JpushService jpushService;
}
